package tech.mhuang.pacebox.oss;

import tech.mhuang.pacebox.core.chain.BaseChain;
import tech.mhuang.pacebox.core.chain.ChainAdapter;
import tech.mhuang.pacebox.oss.domain.OssDeleteRequest;
import tech.mhuang.pacebox.oss.domain.OssDeleteResult;
import tech.mhuang.pacebox.oss.domain.OssDownloadRequest;
import tech.mhuang.pacebox.oss.domain.OssDownloadResult;
import tech.mhuang.pacebox.oss.domain.OssUploadRequest;
import tech.mhuang.pacebox.oss.domain.OssUploadResult;
import tech.mhuang.pacebox.oss.interceptor.OssDeleteInteceptor;
import tech.mhuang.pacebox.oss.interceptor.OssDownloadInterceptor;
import tech.mhuang.pacebox.oss.interceptor.OssUploadInterceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * OSS模板使用
 *
 * @author mhuang
 * @since 1.0.0
 */
public class OssTemplate implements OssOperation {

    private Map<String, BaseOssHandler> ossHandlerMap = new ConcurrentHashMap<>();
    private List<OssUploadInterceptor> uploadInterceptorList = new CopyOnWriteArrayList<>();
    private List<OssDownloadInterceptor> downloadInterceptorList = new CopyOnWriteArrayList<>();
    private List<OssDeleteInteceptor> deleteInteceptorList = new CopyOnWriteArrayList<>();

    @Override
    public void addHandler(String key, BaseOssHandler ossHandler) {
        ossHandlerMap.put(key, ossHandler);
    }

    @Override
    public void addUploadIntecptor(OssUploadInterceptor uploadInterceptor) {
        uploadInterceptorList.add(uploadInterceptor);
    }

    @Override
    public void addDownloadInteceptor(OssDownloadInterceptor downloadInterceptor) {
        downloadInterceptorList.add(downloadInterceptor);
    }

    @Override
    public void addDeleteInteceptor(OssDeleteInteceptor deleteInteceptor) {
        deleteInteceptorList.add(deleteInteceptor);
    }

    @Override
    public OssUploadResult upload(OssUploadRequest uploadRequest) {
        List<OssUploadInterceptor> uploadInterceptorList = new ArrayList<>();
        uploadInterceptorList.addAll(this.uploadInterceptorList);
        uploadInterceptorList.add(new OssUploadInterceptor.Standard(ossHandlerMap));
        BaseChain<OssUploadRequest, OssUploadResult> chain = new ChainAdapter(uploadInterceptorList, 0, uploadRequest);
        return chain.proceed(uploadRequest);
    }

    @Override
    public OssDownloadResult download(OssDownloadRequest downloadRequest) {
        List<OssDownloadInterceptor> downloadInterceptorList = new ArrayList<>();
        downloadInterceptorList.addAll(this.downloadInterceptorList);
        downloadInterceptorList.add(new OssDownloadInterceptor.Standard(ossHandlerMap));
        BaseChain<OssDownloadRequest, OssDownloadResult> chain = new ChainAdapter(downloadInterceptorList, 0, downloadRequest);
        return chain.proceed(downloadRequest);
    }

    @Override
    public OssDeleteResult delete(OssDeleteRequest deleteRequest) {
        List<OssDeleteInteceptor> deleteInteceptorList = new ArrayList<>();
        deleteInteceptorList.addAll(this.deleteInteceptorList);
        deleteInteceptorList.add(new OssDeleteInteceptor.Standard(ossHandlerMap));
        BaseChain<OssDeleteRequest, OssDeleteResult> chain = new ChainAdapter(deleteInteceptorList, 0, deleteRequest);
        return chain.proceed(deleteRequest);
    }

    public void setUploadInterceptors(List<OssUploadInterceptor> ossUploadInterceptorList) {
        this.uploadInterceptorList = ossUploadInterceptorList;
    }

    public void setDownloadInterceptors(List<OssDownloadInterceptor> ossDownloadInterceptorList) {
        this.downloadInterceptorList = ossDownloadInterceptorList;
    }

    public void setDeleteInteceptors(List<OssDeleteInteceptor> ossDeleteInteceptorList) {
        this.deleteInteceptorList = ossDeleteInteceptorList;
    }
}
